/**
 * @description 深拷贝
 * @param obj 需要被深拷贝的对象
 * @param hash 一个可选的 WeakMap 对象，用于存储已经拷贝过的对象，以避免循环引用问题 .如果调用 deepCopy 时没有提供 hash 参数，则默认创建一个新的 WeakMap 实例
 * @returns {object}
 */

export function deepCopy(obj, hash = new WeakMap()) {
  // 基本类型检查-如果 obj 不是对象（包括数组、普通对象、函数等）或者它是 null，则直接返回 obj 本身，因为基本类型和 null 不需要深拷贝。
  if (typeof obj !== "object" || obj === null) {
    return obj;
  }
  // 循环引用检查-如果 obj 已经在 hash 中（即之前已经拷贝过），则返回之前拷贝的副本，以避免无限递归和循环引用。
  if (hash.has(obj)) {
    return hash.get(obj);
  }

  //创建副本-根据 obj 的类型（数组或对象）创建一个新的空数组或空对象作为副本。
  let copy = Array.isArray(obj) ? [] : {};
  // 存储原始对象与副本的映射-在 hash 中存储原始对象 obj 和其副本 copy 的映射关系。
  hash.set(obj, copy);

  // 遍历对象的属性-使用 for...in 循环遍历 obj 的所有可枚举属性。如果 obj 本身拥有该属性（而不是从其原型链上继承的），则递归调用 deepCopy 函数来拷贝该属性的值，并将结果存储在副本 copy 的相应属性中。

  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepCopy(obj[key], hash);
    }
  }

  // 返回副本
  return copy;
}
